#ifndef DW_GRAPHICS_COLOR_H
#	define DW_GRAPHICS_COLOR_H

#include "maths/vector.h"

namespace dw {
	namespace graphics {

template< typename T >
struct Color;

template< typename T >
inline Color< T > operator+(const Color< T >& lhs, const Color< T >& rhs);

template< typename T >
inline Color< T > operator-(const Color< T >& lhs, const Color< T >& rhs);

template< typename T >
inline Color< T > operator*(const Color< T >& lhs, const T& rhs);

template< typename T >
inline Color< T > operator*(const T& lhs, const Color< T >& rhs);

template< typename T >
inline Color< T > operator/(const Color< T >& lhs, const T& rhs);

template< typename T >
struct Color
{

// Constructors
public:
	
	inline Color(const Color< T >& color);

	inline Color(const T* data);
	
	inline Color(const T& r = 0, const T& g = 0, const T& b = 0,const T& a = 1);

// Methods
public:

	inline T& operator[](const unsigned i) { dwAssert(i < 4, "Index is out of range"); return data[i]; }

	inline const T& operator[](const unsigned i) const { dwAssert(i < 4, "Index is out of range"); return data[i]; }

	inline Color< T >&	operator=(const Color< T >& rhs);
	
	inline Color< T >&	operator+=(const Color< T >& rhs);
	
	inline Color< T >&	operator-=(const Color< T >& rhs);
	
	inline Color< T >&	operator*=(const T& rhs);
	
	inline Color< T >&	operator/=(const T& rhs);



	static inline T diffuse(const T& kd, const maths::Vector< T, 3 >& N, const maths::Vector< T, 3 >& L);

	static inline T specular(const T& ks, const maths::Vector< T, 3 >& R, const maths::Vector< T, 3 >& V, const T& n);

// Fields
public:

	static const Color< T > Black;
	static const Color< T > Blue;
	static const Color< T > Brown;
	static const Color< T > Cyan;
	static const Color< T > Gold;
	static const Color< T > Grey;
	static const Color< T > Green;
	static const Color< T > Magenta;
	static const Color< T > Orange;
	static const Color< T > Pink;
	static const Color< T > Purple;
	static const Color< T > Red;
	static const Color< T > White;
	static const Color< T > Yellow;
	static const Color< T > LightBlue;

	
	union
	{ 
		T data[4];
		struct
		{
			T r, g, b, a;
		};
	};

};

typedef Color< int >		Colori;

typedef Color< float >	Colorf;

typedef Color< double >	Colord;

	} // namespace graphics
} // namespace dw

#include "graphics/color.inl"

#endif // !DW_GRAPHICS_COLOR_H
